/**
 * Fichier Parametres.java : Définition de classe
 * fr.unice.gnpt.core.util.Parametres : Paramètres de l'application
 * 
 * Auteurs : Groupe GNPT : Gastinel, Nicolas, Pellegrino, Trovato
 */
package fr.unice.gnpt.core.util;

import java.io.File;
import java.util.Properties;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;

import fr.unice.gnpt.Main;

/**
 * Classe de gestion des paramètres de l'application.
 * <p>
 * Cette classe utilise java.util.prefs.Preferences pour sauvegarder les
 * paramètres liées à l'application, et fournit des accesseurs et modifieurs
 * explicites afin d'uniformiser l'accès à l'objet Preferences.
 * <p>
 * Une seule instance de cette classe n'est censé exister durant la vie de
 * l'application, c'est pourquoi le <i>Singleton Design Pattern</i> est utilisé
 * ici.
 * 
 * @author gnpt
 * @version 0.0.1
 */
public class Parametres {
	/**
	 * L'instance statique de cette classe (pour le Singleton Pattern)
	 */
	private static Parametres instance = null;
	/**
	 * L'objet contenant les paramètres utilisateur pour la classe Main
	 */
	private Preferences preferences = null;

	/**
	 * Constructeur pour la classe Parametres
	 */
	protected Parametres() {
		super();
		this.preferences = Preferences.userNodeForPackage(Main.class);
	}

	/**
	 * Accesseur pour l'instance statique de cette classe. L'instance sera créée
	 * lors du premier appel à cette méthode d'instance.
	 * 
	 * @return l'instance existante de cet classe.
	 */
	public static Parametres getParametres() {
		if (Parametres.instance == null) {
			Parametres.instance = new Parametres();
		}
		return Parametres.instance;
	}

	/**
	 * Méthode pour sauvegarder les propriétés
	 * 
	 * @throws ParametresException
	 */
	public void enregistrer() throws ParametresException {
		try {
			this.preferences.sync();
		} catch (BackingStoreException e) {
			throw new ParametresException(
					"Les paramètres n'ont pu être enregistrés", e);
		}
	}

	/**
	 * Accesseur pour les paramètres spécifique à JPA.
	 * <p>
	 * Cette méthode a pour vocation d'être utilisé en second argument de
	 * {@link javax.persistence.Persistence#createEntityManagerFactory(String, java.util.Map) }.
	 * <p>
	 * Cette méthode utilise la propriété {@code sgbd} pour retourner les
	 * paramètres spécifique à un sgbd. Si le paramètre {@code sgbd} n'est pas
	 * utilisable, l'instance de Properties (sous-classe de Map) retournée sera
	 * vide.
	 * 
	 * @return une instance de Properties contenant les paramètres pour JPA.
	 */
	public Properties getProperties() {
		Properties props = new Properties();
		/*
		 * Utilisation de this.preferences à cause de la valeur par défaut de la
		 * méthode getSGBD
		 */
		String sgbd = this.preferences.get("jpa.sgbd", "");
		if (sgbd.equals("oracle")) {
			props.put("jpa.server.type", sgbd);
			props.put("jpa.server", this.getHoteOracle());
			props.put("jpa.port", this.getPortOracle());
			props.put("jpa.database", this.getBaseOracle());
			props.put("jpa.user", this.getUtilisateurOracle());
			props.put("jpa.pass", this.getMotDePasseOracle());
		} else if (sgbd.equals("mysql")) {
			props.put("jpa.server.type", sgbd);
			props.put("jpa.server", this.getHoteMySql());
			props.put("jpa.port", this.getPortMySql());
			props.put("jpa.database", this.getBaseMySql());
			props.put("jpa.user", this.getUtilisateurMySql());
			props.put("jpa.pass", this.getMotDePasseMySql());
		}
		return props;
	}

	/**
	 * Mutateur pour le type d'utilisateur par défaut.
	 * 
	 * @param utilisateur
	 *            le nom du type d'utilisateur sous forme de chaîne de
	 *            caractères.
	 */
	public void setTypeUtilisateur(String utilisateur) {
		if (utilisateur != null)
			this.preferences.put("utilisateur", utilisateur.toLowerCase());
	}

	/**
	 * Accesseur pour le type d'utilisateur par défaut.
	 * 
	 * @return le nom du type d'utilisateur à utiliser.
	 */
	public String getTypeUtilisateur() {
		return this.preferences.get("utilisateur", "enseignant");
	}

	/**
	 * Mutateur pour le gestionnaire de persistance utilisé par défaut.
	 * 
	 * @param gestionnaire
	 *            le nom du gestionnaire sous forme de chaîne de caractères.
	 */
	public void setGestionnairePersistance(String gestionnaire) {
		if (gestionnaire != null)
			this.preferences.put("gestionnaire", gestionnaire.toLowerCase());
	}

	/**
	 * Accesseur pour le gestionnaire de persistance par défaut.
	 * 
	 * @return le nom du gestionnaire à utiliser.
	 */
	public String getGestionnairePersistance() {
		return this.preferences.get("gestionnaire", "db4o");
	}

	/**
	 * Mutateur pour le chemin référençant la base de données db4o.
	 * 
	 * @param chemin
	 *            le chemin sur le système de fichier où enregistrer les
	 *            données.
	 */
	public void setCheminDb4o(String chemin) {
		if (chemin != null)
			this.preferences.put("db4o.chemin", chemin);
	}

	/**
	 * Accesseur pour le chemin référençant la base de données db4o.
	 * 
	 * @return le chemin en tant que chaîne de caractères.
	 */
	public String getCheminDb4o() {
		return this.preferences.get("db4o.chemin", new File(System
				.getProperty("user.home"), "servicesGNPT.data")
				.getAbsolutePath());
	}

	/**
	 * Mutateur pour le serveur de base de données.
	 * 
	 * @param sgbd
	 *            le nom du système de gestion de base de données.
	 */
	public void setSGBD(String sgbd) {
		if (sgbd != null) {
			this.preferences.put("jpa.sgbd", sgbd.toLowerCase());
		}
	}

	/**
	 * Accesseur pour le serveur de base de données.
	 * 
	 * @return le nom du système de gestion de base de données.
	 */
	public String getSGBD() {
		return this.preferences.get("jpa.sgbd", "oracle");
	}

	/**
	 * Mutateur pour le nom d'hôte du serveur Oracle.
	 * 
	 * @param hote
	 *            le nom ou l'adresse du nom d'hôte du serveur oracle.
	 */
	public void setHoteOracle(String hote) {
		if (hote != null) {
			this.preferences.put("jpa.oracle.host", hote);
		}
	}

	/**
	 * Accesseur pour le nom d'hôte du serveur Oracle.
	 * 
	 * @return le nom ou l'adresse du nom d'hôte du serveur oracle.
	 */
	public String getHoteOracle() {
		return this.preferences.get("jpa.oracle.host", "localhost");
	}

	/**
	 * Mutateur pour le port du serveur Oracle.
	 * 
	 * @param port
	 *            le numéro de port du serveur Oracle.
	 */
	public void setPortOracle(String port) {
		if (port != null) {
			this.preferences.put("jpa.oracle.port", port);
		}
	}

	/**
	 * Accesseur pour le port du serveur Oracle.
	 * 
	 * @return le numéro de port du serveur Oracle.
	 */
	public String getPortOracle() {
		return this.preferences.get("jpa.oracle.port", "1521");
	}

	/**
	 * Mutateur pour le nom de la base de données Oracle.
	 * 
	 * @param base
	 *            le nom de la base de données à utiliser.
	 */
	public void setBaseOracle(String base) {
		if (base != null) {
			this.preferences.put("jpa.oracle.base", base);
		}
	}

	/**
	 * Accesseur pour le nom de la base de données Oracle.
	 * 
	 * @return le nom de la base de données à utiliser.
	 */
	public String getBaseOracle() {
		return this.preferences.get("jpa.oracle.base", "XE");
	}

	/**
	 * Mutateur pour le nom d'utilisateur Oracle.
	 * 
	 * @param user
	 *            le nom d'utilisateur à utiliser pour la connexion au sgbd.
	 */
	public void setUtilisateurOracle(String user) {
		if (user != null) {
			this.preferences.put("jpa.oracle.user", user);
		}
	}

	/**
	 * Accesseur pour le nom d'utilisateur Oracle.
	 * 
	 * @return le nom d'utilisateur à utiliser pour la connexion au sgbd.
	 */
	public String getUtilisateurOracle() {
		return this.preferences.get("jpa.oracle.user", "");
	}

	/**
	 * Mutateur pour le mot de passe Oracle.
	 * 
	 * @param pass
	 *            le mot de passe à utiliser pour la connexion au sgbd.
	 */
	public void setMotDePasseOracle(String pass) {
		if (pass != null) {
			this.preferences.put("jpa.oracle.pass", pass);
		}
	}

	/**
	 * Accesseur pour le mot de passe Oracle.
	 * 
	 * @return le mot de passe à utiliser pour la connexion au sgbd.
	 */
	public String getMotDePasseOracle() {
		return this.preferences.get("jpa.oracle.pass", "");
	}

	/**
	 * Mutateur pour le nom d'hôte du serveur MySql.
	 * 
	 * @param hote
	 *            le nom ou l'adresse du nom d'hôte du serveur MySql.
	 */
	public void setHoteMySql(String hote) {
		if (hote != null) {
			this.preferences.put("jpa.mysql.host", hote);
		}
	}

	/**
	 * Accesseur pour le nom d'hôte du serveur MySql.
	 * 
	 * @return le nom ou l'adresse du nom d'hôte du serveur MySql.
	 */
	public String getHoteMySql() {
		return this.preferences.get("jpa.mysql.host", "localhost");
	}

	/**
	 * Mutateur pour le port du serveur MySql.
	 * 
	 * @param port
	 *            le numéro de port du serveur MySql.
	 */
	public void setPortMySql(String port) {
		if (port != null) {
			this.preferences.put("jpa.mysql.port", port);
		}
	}

	/**
	 * Accesseur pour le port du serveur MySql.
	 * 
	 * @return le numéro de port du serveur MySql.
	 */
	public String getPortMySql() {
		return this.preferences.get("jpa.mysql.port", "3306");
	}

	/**
	 * Mutateur pour le nom de la base de données MySql.
	 * 
	 * @param base
	 *            le nom de la base de données à utiliser.
	 */
	public void setBaseMySql(String base) {
		if (base != null) {
			this.preferences.put("jpa.mysql.base", base);
		}
	}

	/**
	 * Accesseur pour le nom de la base de données MySql.
	 * 
	 * @return le nom de la base de données à utiliser.
	 */
	public String getBaseMySql() {
		return this.preferences.get("jpa.mysql.base", "");
	}

	/**
	 * Mutateur pour le nom d'utilisateur MySql.
	 * 
	 * @param user
	 *            le nom d'utilisateur à utiliser pour la connexion au sgbd.
	 */
	public void setUtilisateurMySql(String user) {
		if (user != null) {
			this.preferences.put("jpa.mysql.user", user);
		}
	}

	/**
	 * Accesseur pour le nom d'utilisateur MySql.
	 * 
	 * @return le nom d'utilisateur à utiliser pour la connexion au sgbd.
	 */
	public String getUtilisateurMySql() {
		return this.preferences.get("jpa.mysql.user", "");
	}

	/**
	 * Mutateur pour le mot de passe MySql.
	 * 
	 * @param pass
	 *            le mot de passe à utiliser pour la connexion au sgbd.
	 */
	public void setMotDePasseMySql(String pass) {
		if (pass != null) {
			this.preferences.put("jpa.mysql.pass", pass);
		}
	}

	/**
	 * Accesseur pour le mot de passe MySql.
	 * 
	 * @return le mot de passe à utiliser pour la connexion au sgbd.
	 */
	public String getMotDePasseMySql() {
		return this.preferences.get("jpa.mysql.pass", "");
	}

}
